﻿namespace NJQuery {
	using System;
	using System.Collections.Generic;
	using System.Reflection;

	/// <summary>
	/// Allows the association of a CSS class with each member of the <see cref="PanelType"/> enumeration.
	/// </summary>
	[AttributeUsage(AttributeTargets.Field)]
	public sealed class PanelTypeAttribute : Attribute {


		#region Static Readonly Fields

		private static readonly object loadLock = new object();
		private static readonly Dictionary<PanelType, string> cssClasses = new Dictionary<PanelType, string>();

		#endregion


		#region Static Methods

		/// <summary>
		/// Returns the CSS class associated with a panel type defined by the <see cref="PanelType"/> enumeration.
		/// </summary>
		/// <param name="panelType">The panel type member to cross-reference for a CSS class.</param>
		/// <returns>The associated CSS class.</returns>
		/// <exception cref="ArgumentException">Value is not defined.</exception>
		public static string GetCssClass(PanelType panelType) {
			if(!Enum.IsDefined(typeof(PanelType), panelType)) throw new ArgumentException("Value is not defined.", "panelType");

			string value;
			if(cssClasses.TryGetValue(panelType, out value)) return value;

			lock(loadLock) {

				if(cssClasses.TryGetValue(panelType, out value)) return value;

				FieldInfo fieldInfo = typeof(PanelType).GetField(panelType.ToString());
				object[] panelTypeAttributes = fieldInfo.GetCustomAttributes(typeof(PanelTypeAttribute), false);
				PanelTypeAttribute panelTypeAttribute = (PanelTypeAttribute)panelTypeAttributes[0];
				string cssClass = panelTypeAttribute.CssClass;

				cssClasses.Add(panelType, cssClass);
				return cssClass;
			}
		}

		#endregion


		#region Fields

		private readonly string cssClass;

		#endregion


		#region Constructors

		/// <summary>
		/// Initializes an instance of the <see cref="PanelTypeAttribute"/> class.
		/// </summary>
		/// <param name="cssClass">The CSS class to associate with the attached enumeration member.</param>
		public PanelTypeAttribute(string cssClass) {
			this.cssClass = cssClass;
		}

		#endregion


		#region Properties

		/// <summary>
		/// The CSS class to associate with the attached enumeration member.
		/// </summary>
		public string CssClass {
			get { return cssClass; }
		}

		#endregion


	}

}